package com.ruoyi.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.RandomStringUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.domain.WdyConsume;
import com.ruoyi.system.domain.WdyShoppingCard;
import com.ruoyi.system.domain.WdyUser;
import com.ruoyi.system.mapper.WdyShoppingCardMapper;
import com.ruoyi.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 购物卡 服务层实现
 * 
 * @author ruoyi
 * @date 2020-10-09
 */
@Service
public class WdyShoppingCardServiceImpl extends ServiceImpl<WdyShoppingCardMapper, WdyShoppingCard> implements IWdyShoppingCardService
{


	protected static Logger log = LoggerFactory.getLogger(WdyShoppingCardServiceImpl.class);

	@Autowired
	private ISysDictDataService sysDictDataService;

	@Autowired
	private IWdyConsumeService wdyConsumeService;

	@Autowired
	private IWdyKlineService wdyKlineService;

	@Autowired
	private IWdyUserService wdyUserService;
	/**
     * 查询购物卡信息
     * 
     * @param id 购物卡ID
     * @return 购物卡信息
     */
    @Override
	public WdyShoppingCard selectWdyShoppingCardById(Long id)
	{
	    return baseMapper.selectWdyShoppingCardById(id);
	}
	
	/**
     * 查询购物卡列表
     * 
     * @param wdyShoppingCard 购物卡信息
     * @return 购物卡集合
     */
	@Override
	public List<WdyShoppingCard> selectWdyShoppingCardList(WdyShoppingCard wdyShoppingCard)
	{
	    return baseMapper.selectWdyShoppingCardList(wdyShoppingCard);
	}
	
    /**
     * 新增购物卡
     * 
     * @param wdyShoppingCard 购物卡信息
     * @return 结果
     */
	@Override
	public int insertWdyShoppingCard(WdyShoppingCard wdyShoppingCard)
	{
	    return baseMapper.insertWdyShoppingCard(wdyShoppingCard);
	}
	
	/**
     * 修改购物卡
     * 
     * @param wdyShoppingCard 购物卡信息
     * @return 结果
     */
	@Override
	public int updateWdyShoppingCard(WdyShoppingCard wdyShoppingCard)
	{
	    return baseMapper.updateWdyShoppingCard(wdyShoppingCard);
	}

	/**
     * 删除购物卡对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
	@Override
	public int deleteWdyShoppingCardByIds(String ids)
	{
		return baseMapper.deleteWdyShoppingCardByIds(Convert.toStrArray(ids));
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public String importCard(List<WdyShoppingCard> cardList, String operName) {
		if (StringUtils.isNull(cardList) || cardList.size() == 0)
		{
			throw new BusinessException("导入数据不能为空！");
		}
		List<WdyShoppingCard> list = new ArrayList<>();
		for (WdyShoppingCard card : cardList)
		{
			if(StringUtils.isEmpty(card.getCardNo()) || StringUtils.isEmpty(card.getCardPwd()) || card.getAmount() == null) {
				continue;
			}
			BigDecimal amount = BigDecimalUtil.getPDecimal(card.getAmount(), 0);
			if(amount.compareTo(BigDecimal.ZERO) <= 0) {
				continue;
			}
			card.setAmount(amount);
			list.add(card);
		}
		if(CollectionUtils.isEmpty(list)) {
			throw new BusinessException("导入数据不能为空！");
		}
		this.saveBatch(list);
		return "恭喜您，数据已全部导入成功！共 " + list.size() + " 条";
	}

	@Override
	public JSONArray getExRateArray(String userId) {
		BigDecimal amount = getAmount(userId);
		return getExRateArray(userId, amount);
	}

	@Override
	public JSONArray getExRateArray(String userId, BigDecimal amount) {
		JSONArray rateArray = null;
		List<SysDictData> dictDataList = sysDictDataService.selectDictDataByType("exchange_config");
		for(SysDictData data : dictDataList) {
			BigDecimal limitAmount = new BigDecimal(data.getDictLabel());
			if(amount.compareTo(limitAmount) < 0) {
				rateArray = JSON.parseArray(data.getDictValue());
				break;
			}
		}
		if(rateArray == null) {
			throw new BusinessException(ResultConstants.FI2007, "兑换配置错误");
		}
		return rateArray;
	}

	@Override
	public BigDecimal getAmount(String userId) {
		QueryWrapper<WdyShoppingCard> payQueryWrapper = new QueryWrapper<>();
		payQueryWrapper.select("IFNULL(SUM(amount),0) AS amount");
		payQueryWrapper.eq("user_id", userId);
		Map<String, Object> amountMap = this.getMap(payQueryWrapper);
		return (BigDecimal) amountMap.get("amount");
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void buyShoppingCard(String userId, BigDecimal amount, int num) {
		QueryWrapper<WdyShoppingCard> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("amount", amount);
		queryWrapper.eq("user_id", "");
		queryWrapper.last("limit " + num);
		List<WdyShoppingCard> list = this.list(queryWrapper);
		if(list.size() < num) {
			throw new BusinessException(ResultConstants.FI1000, "库存不足");
		}

		BigDecimal price = wdyKlineService.getYestodayPrice();
		BigDecimal totalAmount = BigDecimalUtil.getP4Decimal(BigDecimalUtil.divide(amount.multiply(new BigDecimal(num)), price)) ;
		JSONArray array = this.getExRateArray(userId);
		BigDecimal vcAmount = BigDecimalUtil.getP4Decimal(totalAmount.multiply(array.getBigDecimal(0)));
		BigDecimal vcConsumeAmount = BigDecimalUtil.getP4Decimal(totalAmount.multiply(array.getBigDecimal(1)));

		QueryWrapper<WdyUser> userQueryWrapper = new QueryWrapper<>();
		userQueryWrapper.select("user_id", "vc_amount", "vc_consume_amount", "vc_withdraw_amount", "version");
		userQueryWrapper.eq("user_id", userId);
		WdyUser user = wdyUserService.getOne(userQueryWrapper);

		if(vcAmount.compareTo(user.getVcAmount()) > 0) {
			throw new BusinessException(ResultConstants.FI1000, "vcAmount余额不足");
		}

		if(vcConsumeAmount.compareTo(user.getVcConsumeAmount()) > 0) {
			BigDecimal userVcConsumeAmount = BigDecimalUtil.getP4Decimal(user.getVcConsumeAmount());
			BigDecimal need = vcConsumeAmount.subtract(userVcConsumeAmount);
			vcAmount = vcAmount.add(need);
			if(vcAmount.compareTo(user.getVcAmount()) > 0) {
				throw new BusinessException(ResultConstants.FI1000, "vcConsumeAmount余额不足");
			}
			vcConsumeAmount = userVcConsumeAmount;
		}

		log.info("vcAmount:{},vcConsumeAmount:{}", vcAmount, vcConsumeAmount);
		String consumeId = RandomStringUtils.getRandomUUID();
		WdyConsume consume = new WdyConsume();
		consume.setUserId(userId);
		consume.setConsumeId(consumeId);
		consume.setVcAmount(vcAmount);
		consume.setVcConsumeAmount(vcConsumeAmount);
		consume.setVcWithdrawAmount(BigDecimal.ZERO);
		consume.setRemark("兑换购物卡");
		wdyConsumeService.consume(consume);

		Date exTime = new Date();
		for(WdyShoppingCard card : list) {
			UpdateWrapper<WdyShoppingCard> updateWrapper = new UpdateWrapper<>();
			updateWrapper.eq("id", card.getId());
			updateWrapper.eq("user_id", "");
			updateWrapper.set("user_id", userId);
			updateWrapper.set("ex_no", consumeId);
			updateWrapper.set("ex_time", exTime);
			if(!this.update(updateWrapper)) {
				throw new BusinessException(ResultConstants.EX9999, "系统异常，请稍后再试");
			}
		}
 	}

}
